package com.example.java8.stream;

import com.example.java8.lambda.Employee;
import com.example.java8.lambda.Status;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author qibao
 * @version v0.1 2020/11/20
 */
public class TestStreamAPI {
    static List<Employee> employees = Arrays.asList(
            new Employee("张三", 30, 10000d, Status.BUSY),
            new Employee("李四", 81, 3000d, Status.BUSY),
            new Employee("王五", 55, 6000d, Status.FREE),
            new Employee("赵六", 18, 4500d, Status.WAIT)
    );

    //    1.创建
//    集合、数组、Stream.of 方法
    //    创建无限流，
    public static void Test0() {
        //    ①.迭代
        System.out.println("----");
        Stream.iterate(0, (x) -> x + 2).forEach(System.out::println);
        //    2.生成
//        Stream.generate(() -> (Math.random() * 100) / 10).forEach(System.out::println);
    }


    //    2.中间操作.不执行任何操作
    //短路，提高效率
//    filter、limit、skip，distinct(hashCode 和 eques ，需要重写)
//    map，映射

    public void test1() {
        employees.stream()
                .map(Employee::getName)
                .forEach(System.out::println);
    }


    //    3.终止操作。一次性执行全部，“惰性求值”
    //内部迭代，迭代由Stream Api完成

    /**
     * allMatch 检查是否匹配所有元素
     * anyMatch 检查是否至少匹配一个元素
     * nonematch 检查是否没有匹配
     * findFirst 返回第一个元素
     * findAny 返回任意一个元素
     * count 返回元素总个数
     * max 返回最大值
     * min 返回最小值
     */
    public static void test2() {
        boolean b0 = employees.stream().allMatch(x -> x.getStatus() == Status.BUSY);
        System.out.println(b0);
        boolean b1 = employees.stream().anyMatch(x -> x.getStatus() == Status.BUSY);
        System.out.println(b1);
        boolean b2 = employees.stream().noneMatch(x -> x.getStatus() == Status.BUSY);
        System.out.println(b2);
        Optional<Employee> optional = employees.stream().sorted((o1, o2) -> Double.compare(o1.getSalarys(), o2.getSalarys()))
                .findFirst();
        optional.orElse(new Employee());

        //获取薪水
        employees.stream()
                .map(Employee::getSalarys);

    }

    /**
     * 贵约 reduce
     * 计算工资总和是多少
     * 收集 collect
     */
    public void test3() {
        Double sum = employees.stream()
                .map(x -> x.getSalarys())
                .reduce(0d, Double::sum);
        System.out.println(sum);

        Set<String> set = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());

        //总数
        employees.stream()
                .map(Employee::getName)
                .collect(Collectors.counting());
        //平均值
        employees.stream()
//                .map(Employee::getSalarys)
                .collect(Collectors.averagingDouble(Employee::getSalarys));
        //总和
        employees.stream()
                .collect(Collectors.summarizingDouble(Employee::getSalarys));
        //最大值
        Optional<Double> max = employees.stream()
                .map(Employee::getSalarys)
                .collect(Collectors.maxBy(Double::compareTo));

        //最小值
        Optional<Double> min = employees.stream()
                .map(Employee::getSalarys)
                .collect(Collectors.minBy(Double::compareTo));

        //无限分组
//        employees.stream().collect(Collectors.groupingBy(Employee::getStatus), Collectors.groupingBy(
//                (e) -> {
//
//                }
//        ));

        //分区

        //Summary （包含总数，平均数）

        //
    }

    public static Stream<Character> getCharacter(String s) {
        List<Character> characterList = new ArrayList<>();
        for (Character character : s.toCharArray()) {
            characterList.add(character);
        }
        return characterList.stream();
    }

    public static void main(String[] args) {
        employees.stream()
                .map(Employee::getName)
                .flatMap(TestStreamAPI::getCharacter)
                .forEach(System.out::println);
    }
}
